﻿using UnityEditor;
using UnityEngine;
using System;
using System.IO;
using System.Linq;
using System.Collections;
using System.Collections.Generic;

namespace Hont.C2UTool
{
    public static class ShaderInfoHelper
    {
        public enum ShaderPropertyTypeEnum
        {
            Tex2D,
            TexCube,
            Color,
            Vector,
            Float,
            Keyword,
        }

        public struct ShaderTextureInfo
        {
            public Vector2 Offset;
            public Vector2 Scale;
        }

        public struct ShaderProperty
        {
            public ShaderPropertyTypeEnum PropType;
            public string Name;
            public object Value;
        }

        public static ShaderProperty[] GetFields(Material material)
        {
            var shader = material.shader;
            var shaderFieldList = new List<ShaderProperty>();

            #region --- Propertys ---

            var propCount = ShaderUtil.GetPropertyCount(shader);

            for (int i = 0; i < propCount; i++)
            {
                var shaderField = new ShaderProperty();

                shaderField.Name = ShaderUtil.GetPropertyName(shader, i);
                var sourcePropType = ShaderUtil.GetPropertyType(shader, i);

                var dim = ShaderUtil.GetTexDim(shader, i);

                switch (sourcePropType)
                {
                    case ShaderUtil.ShaderPropertyType.Color:
                        shaderField.PropType = ShaderPropertyTypeEnum.Color;
                        shaderField.Value = material.GetColor(shaderField.Name);
                        break;
                    case ShaderUtil.ShaderPropertyType.Float:
                    case ShaderUtil.ShaderPropertyType.Range:
                        shaderField.PropType = ShaderPropertyTypeEnum.Float;
                        shaderField.Value = material.GetFloat(shaderField.Name);
                        break;
                    case ShaderUtil.ShaderPropertyType.TexEnv:
                        switch (dim)
                        {
                            case UnityEngine.Rendering.TextureDimension.Any:
                            case UnityEngine.Rendering.TextureDimension.None:
                            case UnityEngine.Rendering.TextureDimension.Tex3D:
                                break;

                            case UnityEngine.Rendering.TextureDimension.Tex2D:
                                shaderField.PropType = ShaderPropertyTypeEnum.Tex2D;
                                shaderField.Value = new ShaderTextureInfo() { Offset = material.GetTextureOffset(shaderField.Name), Scale = material.GetTextureScale(shaderField.Name) };
                                break;

                            case UnityEngine.Rendering.TextureDimension.Cube:
                                shaderField.PropType = ShaderPropertyTypeEnum.TexCube;
                                break;

                            case UnityEngine.Rendering.TextureDimension.Tex2DArray:
                                break;
                        }
                        break;
                    case ShaderUtil.ShaderPropertyType.Vector:
                        shaderField.PropType = ShaderPropertyTypeEnum.Vector;
                        shaderField.Value = material.GetVector(shaderField.Name);
                        break;
                }

                shaderFieldList.Add(shaderField);
            }
            #endregion

            #region --- Keywords ---
            foreach (var shaderKeyword in material.shaderKeywords)
            {
                shaderFieldList.Add(new ShaderProperty()
                {
                    Name = shaderKeyword,
                    PropType = ShaderPropertyTypeEnum.Keyword,
                    Value = true,
                });
            }

            #endregion

            return shaderFieldList.ToArray();
        }
    }
}
